"""TCP Server module provides a TCP server and a TCP client

"""

import socket
import socketserver
import ma.log
import time
import threading


class DummyEchoRequestHandler(socketserver.BaseRequestHandler):
    """Just a demo class passed to the SocketServer for serving each client
    request. Pass a class inheriting from BaseRequestHandler 
    """
    
    def __init__(self, request, client_address, server):
        # initialize __log for Dummy Request Handler
        self.__log = ma.log.get_logger("ma.net")
        self.__log.warning('Using DUMMY echo request handler class - Implement your own')
        
        try:
            socketserver.BaseRequestHandler.__init__(self, request, client_address, server)
            self.__log.debug('completed init of Dummy echo request handler')
        except Exception as err_msg:
            self.__log.error("Error while creating Dummy Echo Handler: %s", err_msg)
        

    def handle(self):
        # Echo the back to the client
        try:
            data = self.request.recv(1024)
            cur_thread = threading.currentThread()
            response = '%s: %s' % (cur_thread.getName(), data)
            #self.__log.debug('sending response to client')
            self.request.send(response)
            time.sleep(30)
            self.__log.debug('sent response to client')
        except Exception as err_msg:
            self.__log.error("Error while serving client: %s", err_msg)
    
    
    def finish(self):
        self.__log.debug('Dummy Echo Request Handler: finished serving client')
        return socketserver.BaseRequestHandler.finish(self)


class ThreadedTCPServer(socketserver.ThreadingTCPServer):
    """TCP Server class's main purpose is to bind and listen to a certain
    address, port and then call a user function on receiving a packet
    """
    
    def __init__(self, binding_addr, binding_port, handler_class=DummyEchoRequestHandler, args=[]):
        """Constructor for Threaded TCP Server"""
        #initialize __log for TCP Server
        self.__log = ma.log.get_logger("ma.net")
        
        try:
            # get network parameters for address/port
            self.__binding_address = (binding_addr, binding_port)
            # init base class of ThreadingTCPServer
            socketserver.ThreadingTCPServer.__init__(self, self.__binding_address, handler_class)
            
            #save the arguments list
            self.args_list = args
            
            self.__log.info('completed init of Threaded TCP Server at %s', str(self.__binding_address))
        except Exception as err_msg:
            self.__log.error("Error while creating Threaded TCP Server: %s", err_msg)

    """
    def serve_forever(self):
        #Method looped for handling clients. Run when TCP server thread started
        self.__log.info('Started Threaded TCP Server ... waiting for clients')
        while True:
            self.handle_request()
        return
    
    def handle_request(self):
        #Method handling individual client request
        self.__log.debug('Threaded TCP Server handling client request')
        return SocketServer.ThreadingTCPServer.handle_request(self)
    """
    
    def server_close(self):
        """Method called to close server"""
        self.__log.info('Closing Threaded TCP Server')
        return socketserver.TCPServer.server_close(self)
